#include "Cpersuit.h"
#include <Cmaid.h>
#include <Ecore_Data.h>
#include <Eina.h>
#include <stdlib.h>
#include <string.h>

static char *sample_text = "A";

void
cmaid_list_test(unsigned int run, Cps_Stopwatch watches[], Cmaid_List *list)
{
	int i;
	Cmaid_Iter iter;
	const char *text;
	size_t len = 0;

	/* apppend */
	cps_stopwatch_start(&watches[0]);
	for (i = 0; i < run; i++)
	{
		cmaid_list_append(list, sample_text);
	}
	cps_stopwatch_stop(&watches[0]);

	/* iterate */
	cps_stopwatch_start(&watches[1]);
	cmaid_container_iter_attach(list, &iter);
	while ((text = cmaid_iter_next(&iter)))
	/* do something */
		len += strlen(text);
	cmaid_container_iter_detach(list, &iter);
	cps_stopwatch_stop(&watches[1]);

	/* last remove */
	cps_stopwatch_start(&watches[2]);
	while (!cmaid_container_empty_is(list))
		cmaid_list_last_remove(list);
	cps_stopwatch_stop(&watches[2]);
	
	/* prepend */
	cps_stopwatch_start(&watches[3]);
	for (i = 0; i < run; i++)
		cmaid_list_prepend(list, sample_text);
	cps_stopwatch_stop(&watches[3]);

	/* first remove */
	cps_stopwatch_start(&watches[4]);
	while (!cmaid_container_empty_is(list))
		cmaid_list_first_remove(list);
	cps_stopwatch_stop(&watches[4]);
}

void
cmaid_list_test_linked_list(unsigned int run, Cps_Stopwatch watches[])
{
	Cmaid_List *list = cmaid_linked_list_new(NULL);
	cmaid_list_test(run, watches, list);
	cmaid_container_destroy(list);
}

void
cmaid_list_test_vector(unsigned int run, Cps_Stopwatch watches[])
{
	Cmaid_List *list = cmaid_vector_list_new(NULL);
	cmaid_list_test(run, watches, list);
	cmaid_container_destroy(list);
}

void
cmaid_list_test_linked_list_with_iter(unsigned int run, Cps_Stopwatch watches[])
{
	Cmaid_Iter iter;
	Cmaid_List *list = cmaid_linked_list_new(NULL);

	cmaid_container_iter_attach(list, &iter);
	cmaid_list_test(run, watches, list);
	cmaid_container_iter_detach(list, &iter);
	cmaid_container_destroy(list);
}

void
cmaid_list_test_vector_with_iter(unsigned int run, Cps_Stopwatch watches[])
{
	Cmaid_Iter iter;
	Cmaid_List *list = cmaid_vector_list_new(NULL);

	cmaid_container_iter_attach(list, &iter);
	cmaid_list_test(run, watches, list);
	cmaid_container_iter_detach(list, &iter);
	cmaid_container_destroy(list);
}


void
ecore_dlist_test(unsigned int run, Cps_Stopwatch watches[])
{
	int i;
	Ecore_DList *list;
	const char *text;
	size_t len = 0;

	list = ecore_dlist_new();

	printf("run: %d\n", run);
	/* apppend */
	cps_stopwatch_start(&watches[0]);
	for (i = 0; i < run; i++)
	{
		ecore_dlist_append(list, sample_text);
	}
	cps_stopwatch_stop(&watches[0]);

	/* iterate */
	cps_stopwatch_start(&watches[1]);
	ecore_dlist_first_goto(list);
	while ((text = ecore_dlist_next(list)))
	/* do something */
		len += strlen(text);
	cps_stopwatch_stop(&watches[1]);

	/* last remove */
	cps_stopwatch_start(&watches[2]);
	while (!ecore_dlist_empty_is(list))
		ecore_dlist_last_remove(list);
	cps_stopwatch_stop(&watches[2]);
	
	/* prepend */
	cps_stopwatch_start(&watches[3]);
	for (i = 0; i < run; i++)
		ecore_dlist_prepend(list, sample_text);
	cps_stopwatch_stop(&watches[3]);

	/* first remove */
	cps_stopwatch_start(&watches[4]);
	while (!ecore_dlist_empty_is(list))
		ecore_dlist_first_remove(list);
	cps_stopwatch_stop(&watches[4]);
}

void
eina_list_test(unsigned int run, Cps_Stopwatch watches[])
{
	int i;
	Eina_List *l, *list = NULL;
	const char *text;
	size_t len = 0;

	eina_init();

	/* apppend */
	cps_stopwatch_start(&watches[0]);
	for (i = 0; i < run; i++)
	{
		list = eina_list_append(list, sample_text);
	}
	cps_stopwatch_stop(&watches[0]);

	/* iterate */
	cps_stopwatch_start(&watches[1]);
	EINA_LIST_FOREACH(list, l, text)
	/* do something */
		len += strlen(text);
	cps_stopwatch_stop(&watches[1]);

	/* last remove */
	cps_stopwatch_start(&watches[2]);
	while (eina_list_count(list))
		list = eina_list_remove_list(list, eina_list_last(list));
	cps_stopwatch_stop(&watches[2]);
	
	/* prepend */
	cps_stopwatch_start(&watches[3]);
	for (i = 0; i < run; i++)
		list = eina_list_prepend(list, sample_text);
	cps_stopwatch_stop(&watches[3]);

	/* first remove */
	cps_stopwatch_start(&watches[4]);
	while (eina_list_count(list))
		list = eina_list_remove_list(list, list);
	cps_stopwatch_stop(&watches[4]);

	//eina_shutdown();
}

#define START 1
#define STOP  1000
#define STEP  1

CPS_RUN_LIST
	CPS_RUN("Ecore", "DList", ecore_dlist_test,
			START, STOP, STEP,
		       	CPS_TEST("Append", CPS_O_LINEAR),
			CPS_TEST("Iterate", CPS_O_LINEAR),
			CPS_TEST("Last Remove", CPS_O_LINEAR),
			CPS_TEST("Prepend", CPS_O_LINEAR),
			CPS_TEST("First Remove", CPS_O_LINEAR)
		),
	CPS_RUN("Cmaid", "Linked List", cmaid_list_test_linked_list,
			START, STOP, STEP,
		       	CPS_TEST("Append", CPS_O_LINEAR),
			CPS_TEST("Iterate", CPS_O_LINEAR),
			CPS_TEST("Last Remove", CPS_O_LINEAR),
			CPS_TEST("Prepend", CPS_O_LINEAR),
			CPS_TEST("First Remove", CPS_O_LINEAR)
		),
	CPS_RUN("Cmaid", "Vector", cmaid_list_test_vector,
			START, STOP, STEP,
		       	CPS_TEST("Append", CPS_O_LINEAR),
			CPS_TEST("Iterate", CPS_O_LINEAR),
			CPS_TEST("Last Remove", CPS_O_LINEAR),
			CPS_TEST("Prepend", CPS_O_SQUARE),
			CPS_TEST("First Remove", CPS_O_SQUARE)
		),
	CPS_RUN("Cmaid", "Linked List with Iter",
			cmaid_list_test_linked_list_with_iter,
			START, STOP, STEP,
		       	CPS_TEST("Append", CPS_O_LINEAR),
			CPS_TEST("Iterate", CPS_O_LINEAR),
			CPS_TEST("Last Remove", CPS_O_LINEAR),
			CPS_TEST("Prepend", CPS_O_LINEAR),
			CPS_TEST("First Remove", CPS_O_LINEAR)
		),
	CPS_RUN("Cmaid", "Vector with Iter", cmaid_list_test_vector_with_iter,
			START, STOP, STEP,
		       	CPS_TEST("Append", CPS_O_LINEAR),
			CPS_TEST("Iterate", CPS_O_LINEAR),
			CPS_TEST("Last Remove", CPS_O_LINEAR),
			CPS_TEST("Prepend", CPS_O_SQUARE),
			CPS_TEST("First Remove", CPS_O_SQUARE)
		),
	CPS_RUN("Eina", "List", eina_list_test,
			START, STOP, STEP,
		       	CPS_TEST("Append", CPS_O_LINEAR),
			CPS_TEST("Iterate", CPS_O_LINEAR),
			CPS_TEST("Last Remove", CPS_O_LINEAR),
			CPS_TEST("Prepend", CPS_O_LINEAR),
			CPS_TEST("First Remove", CPS_O_LINEAR)
		)
CPS_RUN_LIST_END

